home *** CD-ROM | disk | FTP | other *** search
- Path: druid.borland.com!usenet
- From: pete@borland.com (Pete Becker)
- Newsgroups: comp.lang.c++
- Subject: Re: Implicit Typecasting
- Date: 20 Mar 1996 00:21:57 GMT
- Organization: Borland International
- Message-ID: <4inj35$qcp@druid.borland.com>
- References: <1996Mar16.203628.15187@mcs.drexel.edu>
- NNTP-Posting-Host: pbecker.borland.com
- Mime-Version: 1.0
- Content-Type: Text/Plain; charset=ISO-8859-1
- X-Newsreader: WinVN 0.99.5
-
- In article <1996Mar16.203628.15187@mcs.drexel.edu>, ucphinni@mcs.drexel.edu
- says...
- >
- > I am trying to write a personalized C++ library using Codewarrior on
- the
- >Mac platform (the type of platform should not matter. My main concern is
- >portability, followed closely by speed.).
- > The library is going to have all of the basic structures such as a
- >linked list node, different types of stacks, different types of trees,
- >...etc... and some higher order classes, like scheduling algorithms. I
- >have had some success, but there is one nagging question that has been
- >bothering me.
- > In many of my classes, I use inheritence and must change the interface
- >so the client need not worry about the implementation details (standard c++
- >practice) about the interface. For example, in one part of my library, I
- >have something like this:
- >
- >class llNode {
- > typedef llNode ll;
- > public:
- > llNode(ll * anext = NULL) { nextptr = anext;}
- > ll * next(void) { return nextptr;}
- > ll * next(ll * anext) { return nextptr = anext;}
- > ... cut code ...
- > private:
- > ll * nextptr;
- >};
- >
- >class dlNode : public llNode {
- > typedef dlNode dl;
- > public:
- > dlNode(dl * aprev = NULL,dl * anext = NULL) : ll((ll *) anext)
- > { prevptr = aprev;}
- > dl * prev(void) { return (dl *) prevptr.next();}
- > dl * prev(dl * aprev) { return (dl *) prevptr.next((dl *)
- aprev);}
- > dl * next(void) { return (dl *) ll::next();}
- > dl * next(dl * anext) { return (dl *) ll::next((ll *) anext);}
- > }
- > private:
- > ll prevptr;
- >};
- >
- > My question is of a readability more than a functionality concern.
- For
- >the above code, it would seem to me that a lot of meaningless code (just
- >typecasting) is being done. Is there any standard way to eliminate this.
- >In other words, is there a way for the compiler to automatically equate the
- >current class to the superclass and compile it without any warnings (i.e.
- >compiler would replace ll for dl in the abovemented case) In the previous
- >case, this would elimate all of the public member functions in the dlNode.
-
- Well, some of the casts aren't necessary. For instance:
-
- dlNode(dl * aprev = NULL,dl * anext = NULL) : ll((ll *) anext)
-
- can be written just as well without the cast:
-
- dlNode(dl * aprev = NULL,dl * anext = NULL) : ll(anext)
-
- Other casts are necessary, but dangerous. For example:
-
- dl * prev(void) { return (dl *) prevptr.next();}
-
- The cast here is necessary, because prevptr.next() returns an ll*, not a dl*.
- However, the cast is not safe: it is entirely possible to use this class in a
- way that results in the actual type being a pointer to ll, not a pointer to dl:
-
- llNode Node;
- dlNode DNode;
- DNode.llNode::next(Node);
-
- now the nextptr in DNode holds a pointer to an llNode, and calling DNode.next()
- results in a bogus pointer. This can be fixed by making llNode a private base
- or by using it as a member rather than a base. Once you've done that, the
- casts are indeed necessary. When you can prove to yourself that there is no
- code path that can result in getting the wrong type of pointer back you can
- feel safe about the use of the casts.
- -- Pete
-
-